home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / octa209s.zip / octave-2.09 / src / sighandlers.cc < prev    next >
C/C++ Source or Header  |  1997-05-29  |  17KB  |  706 lines

  1. /*
  2.  
  3. Copyright (C) 1996 John W. Eaton
  4.  
  5. This file is part of Octave.
  6.  
  7. Octave is free software; you can redistribute it and/or modify it
  8. under the terms of the GNU General Public License as published by the
  9. Free Software Foundation; either version 2, or (at your option) any
  10. later version.
  11.  
  12. Octave is distributed in the hope that it will be useful, but WITHOUT
  13. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with Octave; see the file COPYING.  If not, write to the Free
  19. Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. */
  22.  
  23. /* Modified by Klaus Gebhardt, 1995 - 1996 */
  24.  
  25. #ifdef HAVE_CONFIG_H
  26. #include <config.h>
  27. #endif
  28.  
  29. #include <cstdlib>
  30. #include <csignal>
  31.  
  32. #include <new>
  33.  
  34. #include <iostream.h>
  35.  
  36. #ifdef HAVE_UNISTD_H
  37. #ifdef HAVE_SYS_TYPES_H
  38. #include <sys/types.h>
  39. #endif
  40. #include <unistd.h>
  41. #endif
  42.  
  43. #ifdef __EMX__
  44. #include <float.h>
  45. #include <sys/uflags.h>
  46. #endif
  47.  
  48. #include "error.h"
  49. #include "load-save.h"
  50. #include "pager.h"
  51. #include "sighandlers.h"
  52. #include "syswait.h"
  53. #include "toplev.h"
  54. #include "utils.h"
  55.  
  56. // Nonzero means we have already printed a message for this series of
  57. // SIGPIPES.  We assume that the writer will eventually give up.
  58. int pipe_handler_error_count = 0;
  59.  
  60. // Nonzero means we can be interrupted.
  61. int can_interrupt = 0;
  62.  
  63. // Allow us to save the signal mask and then restore it to the most
  64. // recently saved value.  This is necessary when using the POSIX
  65. // signal handling interface on some systems calling longjmp out of
  66. // the signal handler to get to the top level on an interrupt doesn't
  67. // restore the original signal mask.  Alternatively, we could use
  68. // sigsetjmp/siglongjmp, but saving and restoring the signal mask
  69. // ourselves works ok and seems simpler just now.
  70.  
  71. #if defined (HAVE_POSIX_SIGNALS)
  72. static sigset_t octave_signal_mask;
  73. #endif
  74.  
  75. #if RETSIGTYPE == void
  76. #define SIGHANDLER_RETURN(status) return
  77. #else
  78. #define SIGHANDLER_RETURN(status) return status
  79. #endif
  80.  
  81. #if defined (MUST_REINSTALL_SIGHANDLERS)
  82. #define MAYBE_REINSTALL_SIGHANDLER(sig, handler) \
  83.   octave_set_signal_handler (sig, handler)
  84. #else
  85. #define MAYBE_REINSTALL_SIGHANDLER(sig, handler) \
  86.   do { } while (0)
  87. #endif
  88.  
  89. #if defined (__EMX__)
  90. #define MAYBE_ACK_SIGNAL(sig) \
  91.   signal (sig, SIG_ACK)
  92. #else
  93. #define MAYBE_ACK_SIGNAL(sig) \
  94.   do { } while (0)
  95. #endif
  96.  
  97. void
  98. octave_save_signal_mask (void)
  99. {
  100. #if defined (HAVE_POSIX_SIGNALS)
  101.   sigprocmask (0, 0, &octave_signal_mask);
  102. #endif
  103. }
  104.  
  105. void
  106. octave_restore_signal_mask (void)
  107. {
  108. #if defined (HAVE_POSIX_SIGNALS)
  109.   sigprocmask (SIG_SETMASK, &octave_signal_mask, 0);
  110. #endif
  111. }
  112.  
  113. static void
  114. my_friendly_exit (const char *sig_name, int sig_number)
  115. {
  116.   static bool been_there_done_that = false;
  117.  
  118.   if (been_there_done_that)
  119.     {
  120. #if defined (SIGABRT)
  121.       octave_set_signal_handler (SIGABRT, SIG_DFL);
  122. #endif
  123.  
  124.       cerr << "error: attempted clean up apparently failed -- aborting...\n";
  125.  
  126.       abort ();
  127.     }
  128.   else
  129.     {
  130.       been_there_done_that = true;
  131.  
  132.       cerr << "\n\nerror: " << sig_name << " -- stopping myself...\n";
  133.  
  134.       save_user_variables ();
  135.  
  136.       clean_up_and_exit (sig_number);
  137.     }
  138. }
  139.  
  140. // I know, not really a signal handler.
  141.  
  142. static void
  143. octave_new_handler (void)
  144. {
  145.   cerr << "error: memory exhausted -- trying to return to prompt\n";
  146.  
  147.   if (can_interrupt)
  148.     {
  149. #ifdef __EMX__
  150.       _uflags (_UF_SBRK_MODEL, _UF_SBRK_ARBITRARY);
  151. #endif
  152.       jump_to_top_level ();
  153.       panic_impossible ();
  154.     }
  155.   else
  156.     my_friendly_exit ("operator new", 1);
  157. }
  158.  
  159. sig_handler *
  160. octave_set_signal_handler (int sig, sig_handler *handler)
  161. {
  162. #if defined (HAVE_POSIX_SIGNALS)
  163.   struct sigaction act, oact;
  164.   act.sa_handler = handler;
  165.   act.sa_flags = 0;
  166.   sigemptyset (&act.sa_mask);
  167.   sigemptyset (&oact.sa_mask);
  168.   sigaction (sig, &act, &oact);
  169.   return oact.sa_handler;
  170. #elif defined (__EMX__)
  171.   sig_handler *signal_handler = signal (sig, handler);
  172.   MAYBE_ACK_SIGNAL(sig);
  173.   return signal_handler;
  174. #else
  175.   return signal (sig, handler);
  176. #endif
  177. }
  178.  
  179. static RETSIGTYPE
  180. generic_sig_handler (int sig)
  181. {
  182.   my_friendly_exit (sys_siglist[sig], sig);
  183.  
  184.   SIGHANDLER_RETURN (0);
  185. }
  186.  
  187. // Handle SIGCHLD.
  188.  
  189. static RETSIGTYPE
  190. sigchld_handler (int sig )
  191. {
  192.   volatile octave_interrupt_handler saved_interrupt_handler
  193.     = octave_ignore_interrupts ();
  194.  
  195.   // I wonder if this is really right, or if SIGCHLD should just be
  196.   // blocked on OS/2 systems the same as for systems with POSIX signal
  197.   // functions.
  198.  
  199. #if defined (__EMX__)
  200.   volatile sig_handler *saved_sigchld_handler
  201.     = octave_set_signal_handler (SIGCHLD, SIG_IGN);
  202. #else
  203.   sigset_t set, oset;
  204.  
  205.   BLOCK_CHILD (set, oset);
  206. #endif
  207.  
  208.   int i = 0;
  209.   int n = octave_child_list::length ();
  210.  
  211.   for (i = 0; i < n; i++)
  212.     {
  213.       octave_child& elt = octave_child_list::elem (i);
  214.  
  215.       pid_t pid = elt.pid;
  216.  
  217.       if (pid > 0)
  218.     {
  219.       int status;
  220.  
  221.       if (waitpid (pid, &status, WNOHANG) > 0)
  222.         {
  223.           elt.pid = -1;
  224.  
  225.           octave_child::dead_child_handler f = elt.handler;
  226.  
  227.           if (f)  f (pid, status);
  228.           else
  229.         {
  230.           string file = elt.filename;
  231.           unlink (file.c_str ());
  232.         }
  233.  
  234.           break;
  235.         }
  236.     }
  237.     }
  238.  
  239.   if (i == n)  waitpid (-1, NULL, WNOHANG);
  240.  
  241.   octave_set_interrupt_handler (saved_interrupt_handler);
  242.  
  243. #ifndef __EMX__
  244.   UNBLOCK_CHILD (oset);
  245. #else
  246.   octave_set_signal_handler (SIGCHLD, saved_sigchld_handler);
  247. #endif
  248.  
  249.   MAYBE_ACK_SIGNAL (SIGCHLD);
  250.  
  251.   MAYBE_REINSTALL_SIGHANDLER (SIGCHLD, sigchld_handler);
  252.  
  253.   SIGHANDLER_RETURN (0);
  254. }
  255.  
  256. #if defined (__alpha__)
  257. static RETSIGTYPE
  258. sigfpe_handler (int sig)
  259. {
  260.   MAYBE_ACK_SIGNAL (SIGFPE);
  261.  
  262.   MAYBE_REINSTALL_SIGHANDLER (SIGFPE, sigfpe_handler);
  263.  
  264.   cerr << "error: floating point exception -- trying to return to prompt\n";
  265.  
  266.   if (can_interrupt)
  267.     {
  268. #if defined (__EMX__)
  269.       _control87 (EM_INVALID | EM_DENORMAL | EM_ZERODIVIDE | EM_OVERFLOW |
  270.           EM_UNDERFLOW | EM_INEXACT, MCW_EM);
  271. #endif
  272.       jump_to_top_level ();
  273.       panic_impossible ();
  274.     }
  275.  
  276.   SIGHANDLER_RETURN (0);
  277. }
  278. #endif
  279.  
  280. // Handle SIGINT by restarting the parser (see octave.cc).
  281. //
  282. // This also has to work for SIGBREAK (on systems that have it), so we
  283. // use the value of sig, instead of just assuming that it is called
  284. // for SIGINT only.
  285.  
  286. static RETSIGTYPE
  287. sigint_handler (int sig)
  288. {
  289.   MAYBE_ACK_SIGNAL (sig);
  290.  
  291.   MAYBE_REINSTALL_SIGHANDLER (sig, sigint_handler);
  292.  
  293.   if (can_interrupt)
  294.     {
  295.       jump_to_top_level ();
  296.       panic_impossible ();
  297.     }
  298.  
  299.   SIGHANDLER_RETURN (0);
  300. }
  301.  
  302. static RETSIGTYPE
  303. sigpipe_handler (int sig)
  304. {
  305.   MAYBE_ACK_SIGNAL (SIGPIPE);
  306.  
  307.   MAYBE_REINSTALL_SIGHANDLER (SIGPIPE, sigpipe_handler);
  308.  
  309.   if (pipe_handler_error_count++ == 0)
  310.     cerr << "warning: broken pipe\n";
  311.  
  312.   // Don't loop forever on account of this.
  313.  
  314.   if (pipe_handler_error_count  > 100)
  315.     jump_to_top_level ();
  316.  
  317.   SIGHANDLER_RETURN (0);
  318. }
  319.  
  320. octave_interrupt_handler
  321. octave_catch_interrupts (void)
  322. {
  323.   octave_interrupt_handler retval;
  324.  
  325. #ifdef SIGINT
  326.   octave_set_signal_handler (SIGINT, sigint_handler);
  327.   retval.int_handler = sigint_handler;
  328.   MAYBE_ACK_SIGNAL (SIGINT);
  329. #endif
  330.  
  331. #ifdef SIGBREAK
  332.   octave_set_signal_handler (SIGBREAK, sigint_handler);
  333.   retval.brk_handler = sigint_handler;
  334.   MAYBE_ACK_SIGNAL (SIGBREAK);
  335. #endif
  336.  
  337.   return retval;
  338. }
  339.  
  340. octave_interrupt_handler
  341. octave_ignore_interrupts (void)
  342. {
  343.   octave_interrupt_handler retval;
  344.  
  345. #ifdef SIGINT
  346.   retval.int_handler = octave_set_signal_handler (SIGINT, SIG_IGN);
  347. #endif
  348.  
  349. #ifdef SIGBREAK
  350.   retval.brk_handler = octave_set_signal_handler (SIGBREAK, SIG_IGN);
  351. #endif
  352.  
  353.   return retval;
  354. }
  355.  
  356. octave_interrupt_handler
  357. octave_set_interrupt_handler (RETSIGTYPE (*f)(int))
  358. {
  359.   octave_interrupt_handler retval;
  360.  
  361.   if (f)
  362.     {
  363. #ifdef SIGINT
  364.       retval.int_handler = octave_set_signal_handler (SIGINT, f);
  365.       MAYBE_ACK_SIGNAL (SIGINT);
  366. #endif
  367.  
  368. #ifdef SIGBREAK
  369.       retval.brk_handler = octave_set_signal_handler (SIGBREAK, f);
  370.       MAYBE_ACK_SIGNAL (SIGBREAK);
  371. #endif
  372.     }
  373.  
  374.   return retval;
  375. }
  376.  
  377. octave_interrupt_handler
  378. octave_set_interrupt_handler (const volatile octave_interrupt_handler& h)
  379. {
  380.   octave_interrupt_handler retval;
  381.  
  382. #ifdef SIGINT
  383.   retval.int_handler = octave_set_signal_handler (SIGINT, h.int_handler);
  384.   MAYBE_ACK_SIGNAL (SIGINT);
  385. #endif
  386.  
  387. #ifdef SIGBREAK
  388.   retval.brk_handler = octave_set_signal_handler (SIGBREAK, h.brk_handler);
  389.   MAYBE_ACK_SIGNAL (SIGBREAK);
  390. #endif
  391.  
  392.   return retval;
  393. }
  394.  
  395. // Install all the handlers for the signals we might care about.
  396.  
  397. void
  398. install_signal_handlers (void)
  399. {
  400.   set_new_handler (octave_new_handler);
  401.  
  402.   octave_catch_interrupts ();
  403.  
  404. #ifdef SIGABRT
  405.   octave_set_signal_handler (SIGABRT, generic_sig_handler);
  406. #endif
  407.  
  408. #ifdef SIGALRM
  409.   octave_set_signal_handler (SIGALRM, generic_sig_handler);
  410. #endif
  411.  
  412. #ifdef SIGBUS
  413.   octave_set_signal_handler (SIGBUS, generic_sig_handler);
  414. #endif
  415.  
  416. #ifdef SIGCHLD
  417.   octave_set_signal_handler (SIGCHLD, sigchld_handler);
  418. #endif
  419.  
  420. #ifdef SIGEMT
  421.   octave_set_signal_handler (SIGEMT, generic_sig_handler);
  422. #endif
  423.  
  424. #ifdef SIGFPE
  425. #if defined (__alpha__)
  426.   octave_set_signal_handler (SIGFPE, sigfpe_handler);
  427. #else
  428.   octave_set_signal_handler (SIGFPE, generic_sig_handler);
  429. #endif
  430. #endif
  431.  
  432. #ifdef SIGHUP
  433.   octave_set_signal_handler (SIGHUP, generic_sig_handler);
  434. #endif
  435.  
  436. #ifdef SIGILL
  437.   octave_set_signal_handler (SIGILL, generic_sig_handler);
  438. #endif
  439.  
  440. #ifdef SIGIOT
  441.   octave_set_signal_handler (SIGIOT, generic_sig_handler);
  442. #endif
  443.  
  444. #ifdef SIGLOST
  445.   octave_set_signal_handler (SIGLOST, generic_sig_handler);
  446. #endif
  447.  
  448. #ifdef SIGPIPE
  449.   octave_set_signal_handler (SIGPIPE, sigpipe_handler);
  450. #endif
  451.  
  452. #ifdef SIGPOLL
  453.   octave_set_signal_handler (SIGPOLL, SIG_IGN);
  454. #endif
  455.  
  456. #ifdef SIGPROF
  457.   octave_set_signal_handler (SIGPROF, generic_sig_handler);
  458. #endif
  459.  
  460. #ifdef SIGQUIT
  461.   octave_set_signal_handler (SIGQUIT, generic_sig_handler);
  462. #endif
  463.  
  464. #ifdef SIGSEGV
  465.   octave_set_signal_handler (SIGSEGV, generic_sig_handler);
  466. #endif
  467.  
  468. #ifdef SIGSYS
  469.   octave_set_signal_handler (SIGSYS, generic_sig_handler);
  470. #endif
  471.  
  472. #ifdef SIGTERM
  473. #ifdef __EMX__
  474.   signal (SIGTERM, SIG_DFL);
  475. #else
  476.   octave_set_signal_handler (SIGTERM, generic_sig_handler);
  477. #endif
  478. #endif
  479.  
  480. #ifdef SIGTRAP
  481.   octave_set_signal_handler (SIGTRAP, generic_sig_handler);
  482. #endif
  483.  
  484. #ifdef SIGUSR1
  485.   octave_set_signal_handler (SIGUSR1, generic_sig_handler);
  486. #endif
  487.  
  488. #ifdef SIGUSR2
  489.   octave_set_signal_handler (SIGUSR2, generic_sig_handler);
  490. #endif
  491.  
  492. #ifdef SIGVTALRM
  493.   octave_set_signal_handler (SIGVTALRM, generic_sig_handler);
  494. #endif
  495.  
  496. #ifdef SIGIO
  497.   octave_set_signal_handler (SIGIO, SIG_IGN);
  498. #endif
  499.  
  500. #ifdef SIGXCPU
  501.   octave_set_signal_handler (SIGXCPU, generic_sig_handler);
  502. #endif
  503.  
  504. #ifdef SIGXFSZ
  505.   octave_set_signal_handler (SIGXFSZ, generic_sig_handler);
  506. #endif
  507. }
  508.  
  509. #ifndef HAVE_SYS_SIGLIST
  510. char *sys_siglist[NSIG + 1] =
  511. {
  512. #ifdef AIX
  513. /* AIX has changed the signals a bit */
  514.   "bogus signal",            /* 0 */
  515.   "hangup",                /* 1  SIGHUP */
  516.   "interrupt",                /* 2  SIGINT */
  517.   "quit",                /* 3  SIGQUIT */
  518.   "illegal instruction",        /* 4  SIGILL */
  519.   "trace trap",                /* 5  SIGTRAP */
  520.   "IOT instruction",            /* 6  SIGIOT */
  521.   "crash likely",            /* 7  SIGDANGER */
  522.   "floating point exception",        /* 8  SIGFPE */
  523.   "kill",                /* 9  SIGKILL */
  524.   "bus error",                /* 10 SIGBUS */
  525.   "segmentation violation",        /* 11 SIGSEGV */
  526.   "bad argument to system call",    /* 12 SIGSYS */
  527.   "write on a pipe with no one to read it", /* 13 SIGPIPE */
  528.   "alarm clock",            /* 14 SIGALRM */
  529.   "software termination signum",    /* 15 SIGTERM */
  530.   "user defined signal 1",        /* 16 SIGUSR1 */
  531.   "user defined signal 2",        /* 17 SIGUSR2 */
  532.   "death of a child",            /* 18 SIGCLD */
  533.   "power-fail restart",            /* 19 SIGPWR */
  534.   "bogus signal",            /* 20 */
  535.   "bogus signal",            /* 21 */
  536.   "bogus signal",            /* 22 */
  537.   "bogus signal",            /* 23 */
  538.   "bogus signal",            /* 24 */
  539.   "LAN I/O interrupt",            /* 25 SIGAIO */
  540.   "PTY I/O interrupt",            /* 26 SIGPTY */
  541.   "I/O intervention required",        /* 27 SIGIOINT */
  542.   "HFT grant",                /* 28 SIGGRANT */
  543.   "HFT retract",            /* 29 SIGRETRACT */
  544.   "HFT sound done",            /* 30 SIGSOUND */
  545.   "HFT input ready",            /* 31 SIGMSG */
  546. #else /* not AIX */
  547. #ifdef __EMX__
  548.   "bogus signal #0",                    /* 0 */
  549.   "hangup",                             /* 1  SIGHUP */
  550.   "interrupt (Ctrl-C)",                 /* 2  SIGINT (Ctrl-C) */
  551.   "quit",                               /* 3  SIGQUIT */
  552.   "illegal instruction",                /* 4  SIGILL */
  553.   "single step",                        /* 5  SIGTRAP */
  554.   "abort",                              /* 6  SIGABRT */
  555.   "EMT instruction",                    /* 7  SIGEMT */
  556.   "floating point exception",           /* 8  SIGFPE */
  557.   "kill",                               /* 9  SIGKILL */
  558.   "bus error",                          /* 10 SIGBUS */
  559.   "segmentation violation",             /* 11 SIGSEGV */
  560.   "bad argument to system call",        /* 12 SIGSYS */
  561.   "broken pipe",                        /* 13 SIGPIPE */
  562.   "alarm clock",                        /* 14 SIGALRM */
  563.   "software termination signum",        /* 15 SIGTERM */
  564.   "user defined signal 1",              /* 16 SIGUSR1 */
  565.   "user defined signal 2",              /* 17 SIGUSR2 */
  566.   "death of a child",                   /* 18 SIGCHLD */
  567.   "bogus signal #20",                   /* 19 */
  568.   "bogus signal #21",                   /* 20 */
  569.   "break (Ctrl-Break)",                 /* 21 SIGBREAK */
  570. #else /* not __EMX__ */
  571.   "bogus signal",            /* 0 */
  572.   "hangup",                /* 1  SIGHUP */
  573.   "interrupt",                /* 2  SIGINT */
  574.   "quit",                /* 3  SIGQUIT */
  575.   "illegal instruction",        /* 4  SIGILL */
  576.   "trace trap",                /* 5  SIGTRAP */
  577.   "IOT instruction",            /* 6  SIGIOT */
  578.   "EMT instruction",            /* 7  SIGEMT */
  579.   "floating point exception",        /* 8  SIGFPE */
  580.   "kill",                /* 9  SIGKILL */
  581.   "bus error",                /* 10 SIGBUS */
  582.   "segmentation violation",        /* 11 SIGSEGV */
  583.   "bad argument to system call",    /* 12 SIGSYS */
  584.   "write on a pipe with no one to read it", /* 13 SIGPIPE */
  585.   "alarm clock",            /* 14 SIGALRM */
  586.   "software termination signum",    /* 15 SIGTERM */
  587.   "user defined signal 1",        /* 16 SIGUSR1 */
  588.   "user defined signal 2",        /* 17 SIGUSR2 */
  589.   "death of a child",            /* 18 SIGCLD */
  590.   "power-fail restart",            /* 19 SIGPWR */
  591. #ifdef sun
  592.   "window size change",                /* 20 SIGWINCH */
  593.   "urgent socket condition",            /* 21 SIGURG */
  594.   "pollable event occured",            /* 22 SIGPOLL */
  595.   "stop (cannot be caught or ignored)", /*  23 SIGSTOP */
  596.   "user stop requested from tty",        /* 24 SIGTSTP */
  597.   "stopped process has been continued",    /* 25 SIGCONT */
  598.   "background tty read attempted",        /* 26 SIGTTIN */
  599.   "background tty write attempted",    /* 27 SIGTTOU */
  600.   "virtual timer expired",            /* 28 SIGVTALRM */
  601.   "profiling timer expired",            /* 29 SIGPROF */
  602.   "exceeded cpu limit",                /* 30 SIGXCPU */
  603.   "exceeded file size limit",            /* 31 SIGXFSZ */
  604.   "process's lwps are blocked",        /*  32 SIGWAITING */
  605.   "special signal used by thread library", /* 33 SIGLWP */
  606. #ifdef SIGFREEZE
  607.   "Special Signal Used By CPR",        /* 34 SIGFREEZE */
  608. #endif
  609. #ifdef SIGTHAW
  610.   "Special Signal Used By CPR",        /* 35 SIGTHAW */
  611. #endif
  612. #endif /* sun */
  613. #endif /* __EMX__ */
  614. #endif /* AIX */
  615.   0
  616.   };
  617. #endif
  618.  
  619. octave_child_list *octave_child_list::instance = 0;
  620.  
  621. void
  622. octave_child_list::do_insert (pid_t pid, octave_child::dead_child_handler f,
  623.                   string name)
  624. {
  625.   // Insert item in first open slot, increasing size of list if
  626.   // necessary.
  627.  
  628.   bool enlarge = true;
  629.  
  630.   for (int i = 0; i < curr_len; i++)
  631.     {
  632.       octave_child& tmp = list (i);
  633.  
  634.       if (tmp.pid < 0)
  635.     {
  636.       list (i) = octave_child (pid, f, name);
  637.       enlarge = false;
  638.       break;
  639.     }
  640.     }
  641.  
  642.   if (enlarge)
  643.     {
  644.       int total_len = list.length ();
  645.  
  646.       if (curr_len == total_len)
  647.     {
  648.       if (total_len == 0)
  649.         list.resize (16);
  650.       else
  651.         list.resize (total_len * 2);
  652.     }
  653.  
  654.       list (curr_len) = octave_child (pid, f, name);
  655.       curr_len++;
  656.     }
  657. }
  658.  
  659. void
  660. octave_child_list::insert (pid_t pid, octave_child::dead_child_handler f,
  661.                string name)
  662. {
  663.   if (! instance)
  664.     instance = new octave_child_list ();
  665.  
  666.   if (instance)
  667.     instance->do_insert (pid, f, name);
  668.   else
  669.     panic_impossible ();
  670. }
  671.  
  672. void
  673. octave_child_list::do_remove (pid_t pid)
  674. {
  675.   // Mark the record for PID invalid.
  676.  
  677.   for (int i = 0; i < curr_len; i++)
  678.     {
  679.       octave_child& tmp = list (i);
  680.  
  681.       if (tmp.pid == pid)
  682.     {
  683.       tmp.pid = -1;
  684.       break;
  685.     }
  686.     }
  687. }
  688.  
  689. void
  690. octave_child_list::remove (pid_t pid)
  691. {
  692.   if (! instance)
  693.     instance = new octave_child_list ();
  694.  
  695.   if (instance)
  696.     instance->do_remove (pid);
  697.   else
  698.     panic_impossible ();
  699. }
  700.  
  701. /*
  702. ;;; Local Variables: ***
  703. ;;; mode: C++ ***
  704. ;;; End: ***
  705. */
  706.